package classloader;

//import com.sun.tools.javac.Main;

import java.io.*;

public class MyClassLoader extends ClassLoader {

    private byte[] getBytes(String filename) throws IOException {
        File file = new File(filename);
        try (FileInputStream fin = new FileInputStream(file)) {
            long len = file.length();
            byte raw[] = new byte[(int) len];
            int r = fin.read(raw);
            if (r != len)
                throw new IOException("Can't read all, " + r + " != " + len);
            return raw;
        }
    }

    private boolean compileWithEXEC(String javaFile) throws IOException {
        System.out.println("CCL: Compiling " + javaFile + "...");
        Process p = Runtime.getRuntime().exec("javac " + javaFile);
        try {
            p.waitFor();
        } catch (InterruptedException ie) {
            System.out.println(ie);
        }
        int status = p.exitValue();
        return status == 0;
    }
//It's work
//    private boolean compileWithToolsJar(String javaFile) throws IOException {
//        String[] args = new String[]{javaFile};
//        int status;
//        try (FileOutputStream out = new FileOutputStream(javaFile.replace(".java", ".class"), false)) {
//            status = Main.compile(args, new PrintWriter(out, true));
//            System.out.println("Compile result" + status);
//        }
//        return status == 0;
//    }

    public Class loadClass(String name, boolean resolve)
            throws ClassNotFoundException {
        Class<?> clazz = null;
        clazz = findLoadedClass(name);
        String fileStub = name.replace('.', '/');
        String javaFilename = fileStub + ".java";
        String classFilename = fileStub + ".class";
        File javaFile = new File(javaFilename);
        File classFile = new File(classFilename);
        if (javaFile.exists() && (!classFile.exists() || javaFile.lastModified() > classFile.lastModified())) {
            try {
                if (!compileWithEXEC(javaFilename) || !classFile.exists()) {
                    throw new ClassNotFoundException("Compile failed: " + javaFilename);
                }
            } catch (IOException ie) {
                throw new ClassNotFoundException(ie.toString());
            }
        }
        try {
            byte raw[] = getBytes(classFilename);
            clazz = defineClass(name, raw, 0, raw.length);
        } catch (IOException ie) {
        }
        if (clazz == null) {
            clazz = findSystemClass(name);
        }
        if (resolve && clazz != null)
            resolveClass(clazz);
        if (clazz == null)
            throw new ClassNotFoundException(name);
        return clazz;
    }
}